/*  This file is part of -_-.

    -_- is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    -_- is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with -_-.  If not, see <http://www.gnu.org/licenses/>.

    Copyright 2012-2013 Oliver Katz */

#include "string.h"
#include "../debug.h"

z_data z_string_new()
{
    _z_string tmp;
    tmp.content = NULL;
    tmp.size = 0;
    return z_data_wrap(&tmp, Z_TYPEID_STR, sizeof(_z_string));
}

z_data *_z_string_new()
{
    z_data *tmp = (z_data *)malloc(sizeof(z_data));
    *tmp = z_string_new();
    return tmp;
}

z_data z_string_new_from(char *s)
{
    Z_WARNING_NULL(s, z_data_init(0, 0));
    _z_string tmp;
    tmp.content = s;
    tmp.size = strlen(s);
    return z_data_wrap(&tmp, Z_TYPEID_STR, sizeof(_z_string));
}

z_data *_z_string_new_from(char *s)
{
    Z_WARNING_NULL(s, NULL);
    z_data *tmp = (z_data *)malloc(sizeof(z_data));
    *tmp = z_string_new_from(s);
    return tmp;
}

int z_string_del(z_data *s)
{
    Z_WARNING_DATA(s, 1);
    return z_data_release(*s);
}

char z_string_at(z_data *s, int idx)
{
    if (idx < 0)
    {
        Z_WARNING("negative indexes don't work (%i)", idx);
        return 0;
    }

    Z_WARNING_DATA(s, 0);
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, 0);

    if (idx >= tmp->size)
    {
        Z_WARNING("string overflow (%i >= %i)", idx, tmp->size);
        return 0;
    }
    return tmp->content[idx];
}

int z_string_size(z_data *s)
{
    Z_WARNING_DATA(s, -1);
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, -1);
    return tmp->size;
}

int z_string_find_string(z_data *s, z_data *p)
{
    Z_WARNING_DATA(s, -1);
    Z_WARNING_DATA(p, -1);
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, -1);
    _z_string *pat = (_z_string *)z_data_src_get(p);
    Z_WARNING_STRING(tmp, -1);
    return strstr(tmp->content, pat->content)-tmp->content;
}

int z_string_find_char(z_data *s, char c)
{
    Z_WARNING_DATA(s, -1);
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, -1);
    return strchr(tmp->content, c)-tmp->content;
}

z_data z_string_substring(z_data *s, int idx0, int idx1)
{
    if (idx0 < 0 || idx1 < 0)
    {
        Z_WARNING("negative indexes don't work (%i or %i)", idx0, idx1);
        return z_data_init(0, 0);
    }

    if (idx0 >= idx1)
    {
        Z_WARNING("indexes overlap (or the first index is larger than the second) (%i >= %i)", idx0, idx1);
        return z_data_init(0, 0);
    }

    Z_WARNING_DATA(s, z_data_init(0, 0));
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, z_data_init(0, 0));
    if (idx1 >= tmp->size)
    {
        Z_WARNING("string overflow (%i >= %i)", idx1, tmp->size);
        return z_data_init(0, 0);
    }
    _z_string rtn;
    rtn.content = tmp->content+idx0;
    rtn.size = idx1-idx0;
    return z_data_wrap(&rtn, Z_TYPEID_STR, sizeof(_z_string));
}

z_data *_z_string_substring(z_data *s, int idx0, int idx1)
{
    Z_WARNING_DATA(s, NULL);
    z_data *tmp = (z_data *)malloc(sizeof(z_data));
    *tmp = z_string_substring(s, idx0, idx1);
    return tmp;
}

char *z_string_safe(z_data *s)
{
    Z_WARNING_DATA(s, NULL);
    _z_string *tmp = (_z_string *)z_data_src_get(s);
    Z_WARNING_STRING(tmp, NULL);
    return strndup(tmp->content, tmp->size);
}
